package org.batatasframework.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.batatasframework.common.ParameterReader;
import org.batatasframework.values.AbstractStringValueGetter;
import org.batatasframework.values.AbstractValueReader;
import org.batatasframework.values.StringValueGetter;
import org.batatasframework.values.ValueGetter;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

/**
 * 对{@link HttpServletRequest}进行封闭，用于读取{@link HttpServletRequest}对象的数据；
 * 读取时会根据需要转成各种需要的值。
 * 
 * @author jackson
 *
 */
public class RequestParameterReader extends AbstractValueReader implements ParameterReader, MultipartFileReader{
	
	private final HttpServletRequest request;
	
	public static RequestParameterReader valueOf(HttpServletRequest request){
		return new RequestParameterReader(request);
	}
	
	public RequestParameterReader(HttpServletRequest request){
		this.request = request;
	}
	
	@Override
	public ValueGetter getValue(String name) {
		return new InternalRequestValueGetter(name);
	}
	
	public Object getAttribute(String name){
		return request.getSession().getAttribute(name);
	}
	
	private class InternalRequestValueGetter extends AbstractStringValueGetter{
		
		private final String paramenterName;
		
		InternalRequestValueGetter(String name){
			paramenterName = parseName(name);
		}
		
		@Override
		protected String internalValue() {
			return request.getParameter(paramenterName);
		}
		
		@Override
		public <T> T getObject(Class<T> clazz) {
			Object value = request.getAttribute(paramenterName);
			if(clazz.isInstance(value)) return clazz.cast(value);
			return super.getObject(clazz);
		}
	}
	
	protected String parseName(String name){
		return name;
	}
	
	@Override
	public String[] arrayString(String name) {
		String[] vs = request.getParameterValues(parseName(name));
		if(null != vs && vs.length > 0) return vs;
		
		return new String[0];
	}
	
	@Override
	public List<String> listString(String name) {
		return Arrays.asList(request.getParameterValues(parseName(name)));
	}
	
	@Override
	public List<Long> listLong(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	private class InternalRequestSubparameter extends RequestParameterReader implements SubparameterReader, Iterable<SubparameterReader>{
		
		/** 当前需要被处理的数据 */
		final String[] values;
		/** 当前处理的数据的位置 */
		int i = 0;
		
		InternalRequestSubparameter(String[] values) {
			super(request);
			this.values = values;
		}
		
		@Override
		protected String parseName(String name) {
			return name + values[i - 1];
		}
		
		@Override
		public Iterator<SubparameterReader> iterator() {
			
			//每次调用这个方法的时候，都应该把指针归0，否则在第二次以上调用这个方法，就无法读取数据了
			i = 0;
			
			return new Iterator<SubparameterReader>(){

				@Override
				public boolean hasNext() {
					return i < values.length;
				}

				@Override
				public SubparameterReader next() {
					return internalNext();
				}

				@Override
				public void remove() { /* 不允许删除 */ }
				
			};
		}
		
		private SubparameterReader internalNext(){
			i++;
			return this;
		}

		@Override
		public ValueGetter sourceValue() {
			return StringValueGetter.valueOf(values[i - 1]);
		}
		
	}

	@Override
	public Iterable<SubparameterReader> parameters(String name) {
		String[] values = request.getParameterValues(parseName(name));
		if(null == values || values.length == 0) return Collections.emptyList();
		return new InternalRequestSubparameter(values);
	}
	
	//---------------  下面是与文件相关的
	
	@Override
	public Collection<MultipartFile> getFiles() {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
		return multipartRequest.getFileMap().values();
	}

	@Override
	public Collection<MultipartFile> getFiles(String name) {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
		List<MultipartFile> files =  multipartRequest.getFiles(parseName(name));
		List<MultipartFile> validFiles = new ArrayList<>();
		if(null != files){
			for(MultipartFile file : files){
				if(file.isEmpty()) continue;
				validFiles.add(file);
			}
		}
		return validFiles;
	}

	@Override
	public Collection<MultipartFile> notEmptyFiles(String name, String message) {
		Collection<MultipartFile> files = getFiles(name);
		Assert.notEmpty(files, message);
		return files;
	}
	
	@Override
	public MultipartFile getFile(String name) {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
		return multipartRequest.getFile(parseName(name));
	}
	
	@Override
	public MultipartFile notEmptyFile(String name, String message) {
		MultipartFile value = getFile(name);
		Assert.notNull(value, message);
		return value;
	}
	
}
